// Copyright (c) 2002-2009 "Neo Technology,"
//     Network Engine for Objects in Lund AB [http://neotechnology.com]
// This file is part of Neo4j.
// 
// Neo4j is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#region Using Directives

using System.Collections.Generic;
using Direction = org.neo4j.graphdb.Direction;
using Node = org.neo4j.graphdb.Node;
using RelationshipType = org.neo4j.graphdb.RelationshipType;
using ReturnableEvaluator = org.neo4j.graphdb.ReturnableEvaluator;
using StopEvaluator = org.neo4j.graphdb.StopEvaluator;

#endregion
namespace org.neo4j.kernel.impl.traversal
{
    /// <summary>
    ///  A traverser that traverses the node space depth-first. Depth-first means that
    /// it fully visits the end-node of the first relationship before it visits the
    /// end-nodes of the second and subsequent relationships. This class is package
    /// private: any documentation interesting to a client programmer should reside
    /// in <seealso cref="InternalTraverser"/>. For some implementation documentation, see
    /// <seealso cref="AbstractTraverser"/>.
    ///  </summary>
    /// <seealso cref= "InternalTraverser"> </seealso>
    /// <seealso cref= "AbstractTraverser"> </seealso>
    /// <seealso cref= "BreadthFirstTraverser"> </seealso>
	internal class DepthFirstTraverser : AbstractTraverser
    {
        #region Private Variables

        /// <summary>
        /// 
        /// </summary>
        private Stack<TraversalPositionImpl> stack;

        #endregion
     
        #region Class Constructors

        ///<summary> 
        /// Creates a DepthFirstTraverser according the contract of
        /// <seealso cref="AbstractTraverser#AbstractTraverser AbstractTraverser"/>. 
        /// </summary>
        internal DepthFirstTraverser(Node startNode, RelationshipType[] traversableRels, Direction[] traversableDirections, RelationshipType[] preservingRels, Direction[] preservingDirections, StopEvaluator stopEvaluator, ReturnableEvaluator returnableEvaluator, RandomEvaluator randomEvaluator)
            : base(startNode, traversableRels, traversableDirections, preservingRels, preservingDirections, stopEvaluator, returnableEvaluator, randomEvaluator)
        {
        }

        #endregion

        #region Implementations
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="position"></param>
		internal override void AddPositionToList(TraversalPositionImpl position)
		{
			this.stack.Push(position);
		}
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
		internal override TraversalPositionImpl GetNextPositionFromList()
		{
			return this.stack.Pop();
		}
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
		internal override bool ListIsEmpty()
		{
			return this.stack.Count == 0;
		}
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
		internal sealed override bool TraverseChildrenInNaturalOrder()
		{
			return false;
		}
        /// <summary>
        /// 
        /// </summary>
		internal override void InitializeList()
		{
			this.stack = new Stack<TraversalPositionImpl>();
        }

        #endregion
    }
}